package com.bbzn.device.client.service.impl;

import com.bbzn.device.client.constant.MongoDbConstant;
import com.bbzn.device.client.dataobject.LocusCoordinate;
import com.bbzn.device.client.service.LocusCoordinateMongoService;
import com.bbzn.device.client.service.SimpleMongoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class LocusCoordinateMongoServiceImpl implements LocusCoordinateMongoService {

    @Autowired
    private SimpleMongoService simpleMongoService;

    //定义一个容量为10000的阻塞队列，BlockingQueue线程安全可以多个生产者同时put
    private BlockingQueue<LocusCoordinate> dataQueue = new LinkedBlockingQueue<LocusCoordinate>(10000);

    private List<LocusCoordinate> list = new ArrayList<LocusCoordinate>();

    @PostConstruct
    public void init() {
        Thread thread = new Thread(() -> {
            log.info("启动批量【GPS轨迹上传】守护线程，启动时间{}", new Date(System.currentTimeMillis()));
            while (Boolean.TRUE) {
                LocusCoordinate poll = null;
                boolean pollTimeOut = false;
                long startTime;
                long endTime;
                try {
                    // poll时设置超时时间为2秒
                    poll = dataQueue.poll(2, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    log.info("启动批量【GPS轨迹上传】守护线程---批量更新Job异常");
                    Thread.currentThread().interrupt();
                }

                if (null != poll) {
                    // poll到任务添加到List中
                    list.add(poll);
                } else {
                    // poll超时，设置超时标志位
                    pollTimeOut = true;
                }

                // 如果任务List等于5000或poll超时且List中还有任务就批量更新
                if (list.size() == 300 ||
                        (pollTimeOut && !CollectionUtils.isEmpty(list))) {
                    startTime = System.currentTimeMillis();
                    simpleMongoService.insertMulti(list, MongoDbConstant.LOCUS_COORDINATE);
                    log.info("启动批量【GPS轨迹上传】守护线程---Job任务批量更新{}条任务,耗时{}毫秒", list.size(),
                            System.currentTimeMillis() - startTime);
                    list.clear();
                }
            }
        });

        thread.setName("job-batchUpdate-deamon");
        // 设置启动的线程为守护线程 直到jvm停了才停止
        thread.setDaemon(true);
        thread.start();
    }


//    @Override
//    public LocusCoordinate findOne(Long id) {
//        return locusCoordinateRepository.findById(id).orElseGet(null);
//    }
//
//    @Override
//    public LocusCoordinate save(LocusCoordinate locusCoordinate) {
//        return locusCoordinateRepository.save(locusCoordinate);
//    }
//
//    @Override
//    public List<LocusCoordinate> queryAll() {
//        return locusCoordinateRepository.findAll();
//    }
//
//    @Override
//    public Page<LocusCoordinate> findAllByCreateTimeBetweenOrderByCreateTime(Date startTime, Date endTime,String imei, int currentPage, int pageSize) {
//        Pageable pageableObj = PageRequest.of(currentPage,pageSize);
//        return locusCoordinateRepository.findAllByCreateTimeBetweenOrderByCreateTime(startTime,endTime,imei,pageableObj);
//    }

    @Override
    public void recordJob(LocusCoordinate job) {
        try {
            dataQueue.put(job);
        } catch (InterruptedException e) {
            log.info("启动批量【GPS轨迹上传】守护线程,批量更新Job入队列异常");
            Thread.currentThread().interrupt();
        }
    }

//    @Override
//    public List<LocusCoordinate> findAllByCreateTimeBetweenOrderByCreateTime(TimePageDTO dto) {
//        Date startDate = DateUtil.stringToDate(dto.getStartTime(),"yyyy-MM-dd HH:mm:ss");
//        Date endDate = DateUtil.stringToDate(dto.getEndTime(),"yyyy-MM-dd HH:mm:ss");
//        return locusCoordinateRepository.findAllByCreateTimeBetweenOrderByCreateTime(startDate,endDate,dto.getImei());
//    }
//
//    @Override
//    public List<TimeDTO> queryDistinctByCreateTimeBetweenOrderByCreateTime(Date startTime, Date endTime) {
//        return locusCoordinateRepository.queryDistinctByCreateTimeOrderByCreateTimeDesc(startTime,endTime);
//    }


}
